package com.forum.service.impl;

import com.forum.common.event.CommentEvent;
import com.forum.common.event.MentionEvent;
import com.forum.common.event.MessageEventPublisher;
import com.forum.common.exception.BusinessException;
import com.forum.mapper.CommentMapper;
import com.forum.mapper.PostMapper;
import com.forum.model.dto.CommentDTO;
import com.forum.model.entity.Comment;
import com.forum.model.entity.Post;
import com.forum.model.vo.CommentVO;
import com.forum.service.CommentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class CommentServiceImpl implements CommentService {


    private final CommentMapper commentMapper;
    private final PostMapper postMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    // 注入消息事件发布服务
    private final MessageEventPublisher messageEventPublisher;
    
    // @用户名的正则表达式
    private static final Pattern MENTION_PATTERN = Pattern.compile("@([\\w\\u4e00-\\u9fa5_-]+)");

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "post_comments", key = "#commentDTO.postId")
    public CommentVO createComment(CommentDTO commentDTO) {
        // 1. 检查帖子是否存在
        Post post = postMapper.selectById(commentDTO.getPostId());
        if (post == null) {
            throw new BusinessException("帖子不存在");
        }

        // 2. 如果是回复评论，检查父评论是否存在
        Comment parentComment = null;
        if (commentDTO.getParentId() != null) {
            parentComment = commentMapper.selectById(commentDTO.getParentId());
            if (parentComment == null) {
                throw new BusinessException("回复的评论不存在");
            }
        }

        // 3. 创建评论
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentDTO, comment);
        comment.setLikes(0);
        comment.setCreatedAt(LocalDateTime.now());
        commentMapper.insert(comment);

        // 4. 更新帖子评论数
        postMapper.incrementComments(commentDTO.getPostId());

        // 5. 清除帖子评论缓存
        redisTemplate.delete("post_comments::" + commentDTO.getPostId());
        
        // 6. 发送评论通知
        try {
            // 如果是对帖子的评论，发送给帖子作者
            if (commentDTO.getParentId() == null && post.getUserId() != null 
                && !commentDTO.getUserId().equals(post.getUserId())) { // 不给自己发通知
                
                CommentEvent event = CommentEvent.postComment(
                    commentDTO.getUserId(),  // 发送者（评论者）
                    post.getUserId(),        // 接收者（帖子作者）
                    post.getId(),            // 帖子ID
                    post.getTitle(),         // 帖子标题
                    comment.getId(),         // 评论ID
                    comment.getContent()     // 评论内容
                );
                messageEventPublisher.publishCommentEvent(event);
                log.info("帖子评论通知发送成功");
            }
            
            // 如果是对评论的回复，发送给原评论作者
            if (parentComment != null && !commentDTO.getUserId().equals(parentComment.getUserId())) {
                CommentEvent event = CommentEvent.commentReply(
                    commentDTO.getUserId(),      // 发送者（回复者）
                    parentComment.getUserId(),   // 接收者（原评论作者）
                    post.getId(),                // 帖子ID
                    post.getTitle(),             // 帖子标题
                    comment.getId(),             // 评论ID
                    comment.getContent(),        // 评论内容
                    parentComment.getId(),       // 父评论ID
                    parentComment.getContent()   // 父评论内容
                );
                messageEventPublisher.publishCommentEvent(event);
                log.info("评论回复通知发送成功");
            }
            
            // 处理@提及
//            processMentions(commentDTO.getUserId(), comment.getContent(), post);
            
        } catch (Exception e) {
            log.error("评论通知发送失败: {}", e.getMessage(), e);
            // 消息发送失败不影响主流程
        }

        // 7. 返回评论视图对象
        return convertToCommentVO(comment);
    }

    @Override
    @Cacheable(value = "post_comments", key = "#postId")
    public List<CommentVO> getPostComments(Long postId) {
        // 1. 获取所有根评论
        List<Comment> rootComments = commentMapper.selectRootComments(postId);
        if (rootComments.isEmpty()) {
            return new ArrayList<>();
        }

        // 2. 获取所有子评论
        List<Long> rootIds = rootComments.stream()
                .map(Comment::getId)
                .toList();
        List<Comment> allChildComments = new ArrayList<>();
        for (Long rootId : rootIds) {
            allChildComments.addAll(commentMapper.selectChildComments(rootId));
        }

        // 3. 构建评论树
        Map<Long, List<CommentVO>> childrenMap = allChildComments.stream()
                .map(this::convertToCommentVO)
                .collect(Collectors.groupingBy(CommentVO::getParentId));

        // 4. 组装评论树
        return rootComments.stream()
                .map(comment -> {
                    CommentVO commentVO = convertToCommentVO(comment);
                    commentVO.setChildren(childrenMap.getOrDefault(comment.getId(), new ArrayList<>()));
                    return commentVO;
                })
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "post_comments", key = "#id")
    public void deleteComment(Long id) {
        Comment comment = commentMapper.selectById(id);
        if (comment == null) {
            throw new BusinessException("评论不存在");
        }

        // 删除评论及其子评论
        commentMapper.deleteById(id);
        List<Comment> children = commentMapper.selectChildComments(id);
        for (Comment child : children) {
            commentMapper.deleteById(child.getId());
        }

        // 更新帖子评论数
        postMapper.decrementComments(comment.getPostId(), 1 + children.size());

        // 清除帖子评论缓存
        redisTemplate.delete("post_comments::" + comment.getPostId());
    }

    /**
     * 重新计算帖子的评论总数
     */
    @Transactional(rollbackFor = Exception.class)
    public void recalculatePostComments(Long postId) {
        // 1. 获取所有根评论数量
        int rootCount = commentMapper.countRootComments(postId);
        
        // 2. 获取所有子评论数量
        int childCount = commentMapper.countChildComments(postId);
        
        // 3. 更新帖子的评论总数
        postMapper.updateComments(postId, rootCount + childCount);
        
        // 4. 清除缓存
        redisTemplate.delete("post_comments::" + postId);
    }

    /**
     * 转换为评论视图对象
     */
    private CommentVO convertToCommentVO(Comment comment) {
        CommentVO commentVO = new CommentVO();
        BeanUtils.copyProperties(comment, commentVO);
        
        // 从数据库获取用户信息
        Map<String, Object> userInfo = commentMapper.selectUserInfo(comment.getUserId());
        if (userInfo != null) {
            commentVO.setNickname((String) userInfo.get("username"));
            commentVO.setAvatar((String) userInfo.get("picture"));
        }
        
        return commentVO;
    }
    
    /*
      处理评论中的@提及
     */
//    private void processMentions(Long commentUserId, String content, Post post) {
//        // 提取所有@用户名
//        Matcher matcher = MENTION_PATTERN.matcher(content);
//        while (matcher.find()) {
//            String username = matcher.group(1);
//
//            try {
//                // 根据用户名查找用户ID
//                Map<String, Object> userInfo = commentMapper.selectUserInfoByUsername(username);
//                if (userInfo != null) {
//                    Long mentionedUserId = Long.valueOf(userInfo.get("id").toString());
//
//                    // 不给自己发通知
//                    if (!commentUserId.equals(mentionedUserId)) {
//                        MentionEvent event = MentionEvent.mentionInComment(
//                            commentUserId,       // 发送者（评论者）
//                            mentionedUserId,     // 接收者（被@的用户）
//                            post.getId(),        // 帖子ID
//                            post.getTitle(),     // 帖子标题
//                            null,                // 评论ID (可能需要获取)
//                            content              // 评论内容
//                        );
//                        messageEventPublisher.publishMentionEvent(event);
//                        log.info("@提及通知发送成功，用户: {}", username);
//                    }
//                }
//            } catch (Exception e) {
//                log.error("@提及通知发送失败，用户: {}, 原因: {}", username, e.getMessage(), e);
//                // 单个@提及失败不影响其他处理
//            }
//        }
//    }
} 